package com.haolijun.eecms.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.json.JSONUtil;
import com.haolijun.eecms.common.R;
import com.haolijun.eecms.common.RedisConstants;
import com.haolijun.eecms.dao.TbNoticeCommentDao;
import com.haolijun.eecms.dao.TbNoticeDao;
import com.haolijun.eecms.entity.TbNotice;
import com.haolijun.eecms.service.NoticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static com.haolijun.eecms.common.RedisConstants.BLOG_LIKED_KEY;
import static com.haolijun.eecms.common.TransitionUtils.arrayConversion;

/**
 * @ClassName NoticeServiceImpl
 * @Description TODO
 * @Author hljstart
 * @Date 2023/3/11 12:15
 * @Version 1.0
 */
@Service
@Slf4j
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private TbNoticeDao noticeDao;

    @Autowired
    private TbNoticeCommentDao noticeCommentDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public R searchNoticeByPage(HashMap param) {
        // 1、 获取当前页数
        int page = (int) param.get("page");
        // 2、获取每一页的记录数
        int length = (int) param.get("length");
        // 3、计算出当前的要开始的页数
        int start = (page - 1) * length;
        // 4、放入到集合中
        param.put("start", start);
        // 5、查询总记录数
        long count = noticeDao.searchNoticeCount(param);
        // 6、获取信息
        List<HashMap> notices = noticeDao.searchNoticeByPage(param);
        arrayConversion(notices);
        // 7、封装数据
        R r = R.ok().data("totalCount", count).data("pageSize", length).data("pageIndex", start).data("notices", notices);
        return r;
    }

    /**
     * 查询公告详情信息
     * @param nid
     * @return
     */
    @Override
    public HashMap searchNoticeById(Integer nid) {
        // 查看公告详情
        HashMap notice = noticeDao.searchNoticeById(nid);
        if(notice != null) {
            String jsonStr = JSONUtil.toJsonStr(notice.get("images"));
            List<String> images = arrayConversion(jsonStr);
            notice.put("images", images);
            // 查询公告的评论
            List<HashMap> noticeComment = noticeCommentDao.searchNoticeComment(nid);
            notice.put("comments", noticeComment);
            // 查看公告是否是自己点过赞的
            this.isNoticeLiked(notice); //isLike：boolean
        }
        return notice;
    }

    @Override
    public HashMap searchNoticeInfo(Integer nid) {
        // 查看公告详情
        HashMap notice = noticeDao.searchNoticeInfo(nid);
        String jsonStr = JSONUtil.toJsonStr(notice.get("images"));
        if(jsonStr == null || "".equals(jsonStr)) {
            List<String> images = new ArrayList<String>();
            notice.put("images",images);
            return notice;
        }
        List<String> images = JSONUtil.toList(jsonStr, String.class);
        notice.put("images", images);
        return notice;
    }

    @Override
    public int update(TbNotice notice) {
        notice.setUpdateTime(new Date());
        int rows = noticeDao.update(notice);
        return rows;
    }

    @Override
    public int insert(TbNotice notice) {
        // 1、设置参数
        notice.setPublishTime(new Date());
        notice.setUpdateTime(new Date());
        Integer userId = StpUtil.getLoginIdAsInt();
        notice.setUserId(userId);
        // 2、添加到数据库
        int row = noticeDao.insert(notice);
        return row;
    }

    @Transactional
    @Override
    public int deleteNoticeById(Integer nid) {
        HashMap hashMap = this.searchNoticeById(nid);
        int amount = (int) hashMap.get("amount");
        // 1、删除公告
        int rows = noticeDao.deleteNoticeById(nid);
        // 2、删除公告的评论
        if (amount > 0){
            noticeCommentDao.delete(nid);
        }
        return rows;
    }

    @Override
    public int updateCommentCount() {
        int rows = noticeDao.updateCommentCount();
        return rows;
    }

    /**
     * 点赞功能
     * @param nid
     * @return
     */
    @Override
    public R likeNotice(Integer nid) {
        // 1、获取当前用户信息
        Integer userId = StpUtil.getLoginIdAsInt();
        // 2、去Redis中判断当前用户是否已经点赞
        String key = BLOG_LIKED_KEY + nid;
        Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
        // 3、如果没有点赞，可以点赞
        if(BooleanUtil.isFalse(isMember)){
            // 3.1、数据库点赞,点赞数+1
            int rows = noticeDao.updateLikeAdd();
            if(rows > 0){
                redisTemplate.opsForSet().add(key,userId.toString());
            }
        }else {
            int rows = noticeDao.updateLikeReduce();
            if(rows > 0){
                redisTemplate.opsForSet().remove(key,userId.toString());
            }
        }
        return R.ok();
    }

    private void  isNoticeLiked(HashMap notice){
        // 1、获取当前登录用户
        Integer userId = StpUtil.getLoginIdAsInt();
        // 2、判断当前用户是否已经点过赞
        // notice:liked:1
        String key = BLOG_LIKED_KEY + notice.get("id");
        Boolean isMember = redisTemplate.opsForSet().isMember(key, userId.toString());
        notice.put("isLike", BooleanUtil.isTrue(isMember));

    }
}
